package com.dongdong.zhuangji.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.dongdong.zhuangji.entity.ControlPoints;
import com.dongdong.zhuangji.entity.PileData;
import com.dongdong.zhuangji.entity.dto.PilePouringRecord;
import com.dongdong.zhuangji.entity.dto.PileRecord;
import com.dongdong.zhuangji.entity.dto.ReceiptStatementPile;
import com.dongdong.zhuangji.excel.pile.ApplicationFormforConstructionQualityInspectionandApprovalofUnitProject;
import com.dongdong.zhuangji.mapper.PileDataMapper;
import com.dongdong.zhuangji.service.ControlPointsService;
import com.dongdong.zhuangji.service.PileDataService;
import com.dongdong.zhuangji.utils.*;
import com.dongdong.zhuangji.utils.imageUtils.InsertIntoExistingExcel;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.text.DecimalFormat;
import java.util.*;
import java.util.List;

@Service
public class PileDataServiceImpl extends ServiceImpl<PileDataMapper, PileData> implements PileDataService {
    @Autowired
    PileDataMapper pileDataMapper;
    @Autowired
    DateToDayTime dateToDayTime;

    @Autowired
    ControlPointsService controlPointsService;

    public boolean updateById(PileData pileData){
       int i= pileDataMapper.updateById(pileData);
       return i==1;
    }

    /**
     *  生成桩基混凝浇筑记录表
     * @param id
     * @param response
     */

    @Override
    public void createPuringTable(int id,HttpServletResponse response) {
        //根据查询桩信息
        PileData pileData = pileDataMapper.selectById(id);
        // 创建记录列表
        PilePouringRecord pilePouringRecord = createPileRecord(pileData);
        // 创建放样记录
        List <ControlPoints> controlPoints=controlPointsService.list();
        //确定控制点JM1，JM2
        ControlPoints controlPoint=getControlpoint(pileData,controlPoints);
        ControlPoints controlPoint1=getControlpoint(controlPoint,controlPoints);

        try{
            InputStream inputStream=this.getClass().getClassLoader().getResourceAsStream("template/桩基质检及收方资料.xlsx");
            if (inputStream != null) {
                XSSFWorkbook excel=new XSSFWorkbook(inputStream);
                //混凝土浇筑记录表
                createSheet1(excel, pilePouringRecord);
                //放样记录表
                createSheet2(excel, controlPoint, controlPoint1, pileData);
                  //地面标高(m)
                double elevation=pileData.getPileTopElevation()+generateRandomNumber(1,1.2);
                //岩面标高(m	)
                double surfaceelevation=elevation-generateRandomNumber(12,15);
                //护筒顶口标高(m)
                double casingTopElevation= Double.valueOf(pilePouringRecord.getCasingTopElevation());
                //钻孔深度(m)
                double drillingDepth=elevation-Double.valueOf(pilePouringRecord.getPrePouringHoleBottomElevation());

                //成孔记录表
               // creatSheet3(excel, pilePouringRecord, elevation, pileData, casingTopElevation, surfaceelevation, drillingDepth);
                //收方记录表



                //目标文件名称
                String filename=pileData.getPileNumber()+"#桩基质检及收方资料.xlsx";
                String agent= response.getHeader("User-Agent");
                filename= encodeFileName(agent,filename);
                response.setHeader("Content-Type", "application/vnd.ms-excel");
                response.setHeader("Content-Disposition","attachment;filename="+filename);

                ServletOutputStream outputStream=response.getOutputStream();
                excel.write(outputStream);

                outputStream.flush();
                outputStream.close();
                excel.close();
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    /**
     *
     * @param id
     * @param response
     */
    //@Override
    public void createPuringTabletoMiniobak(int id, HttpServletResponse response) {
        //根据查询桩信息
        PileData pileData = pileDataMapper.selectById(id);
        // 创建记录列表
        PilePouringRecord pilePouringRecord = createPileRecord(pileData);
        // 创建放样记录
        List<ControlPoints> controlPoints = controlPointsService.list();
        //确定控制点JM1，JM2
        ControlPoints controlPoint = getControlpoint(pileData, controlPoints);
        ControlPoints controlPoint1 = getControlpoint(controlPoint, controlPoints);

        // 用于存储生成的Excel文件的临时路径
        Path tempFilePath = null;
        FileOutputStream fos = null;

        try {
            InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("template/桩基质检及收方资料.xlsx");
            if (inputStream != null) {
                XSSFWorkbook excel = new XSSFWorkbook(inputStream);
                //混凝土浇筑记录表
                createSheet1(excel, pilePouringRecord);
                //混凝土申请记录表
                createSheet8(excel, pilePouringRecord);
                //放样记录表
                createSheet2(excel, controlPoint, controlPoint1, pileData);
                //地面标高(m)
                double elevation = pileData.getPileTopElevation() + generateRandomNumber(1, 1.2);
                //岩面标高(m)
                double surfaceelevation = elevation - generateRandomNumber(12, 15);
                //护筒顶口标高(m)
                double casingTopElevation = Double.valueOf(pilePouringRecord.getCasingTopElevation());
                //钻孔深度(m)
                double drillingDepth = elevation - Double.valueOf(pilePouringRecord.getPrePouringHoleBottomElevation());

                //成孔记录表
               // creatSheet3(excel, pilePouringRecord, elevation, pileData, casingTopElevation, surfaceelevation, drillingDepth);

                // 创建临时文件
                tempFilePath = Files.createTempFile("pile-data-", ".xlsx");
                File tempFile = tempFilePath.toFile();
                fos = new FileOutputStream(tempFile);
                excel.write(fos);
                fos.flush();

                // 关闭Excel工作簿和流
                excel.close();
                inputStream.close();
                fos.close();

                // 准备上传文件到微服务
                String pileNumber = pileData.getPileNumber();
                //todo  Long userId = getCurrentUserId(); // 需要实现这个方法获取当前用户ID
                Long userId = 1L; // 需要实现这个方法获取当前用户ID
                String operation = "资料数据"; // 操作类型，可根据实际情况修改

                // 创建RestTemplate实例
                RestTemplate restTemplate = new RestTemplate();

                // 设置请求头
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.MULTIPART_FORM_DATA);

                // 创建文件系统资源
                FileSystemResource fileResource = new FileSystemResource(tempFile);

                // 构建表单数据
                MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
                body.add("file", fileResource);
                body.add("userId", userId);
                body.add("pileNumber", pileNumber);
                body.add("operation", operation);


                // 创建HTTP请求
                HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);

                // 微服务上传接口URL
               // String uploadUrl = "http://your-microservice-url/upload";
                String uploadUrl = "http://192.168.1.245:8081/file/upload";

                // 发送请求并获取响应
               // ResponseEntity<String> responseEntity = restTemplate.postForEntity(uploadUrl, requestEntity, String.class);
                ResponseEntity<String> responseEntity = restTemplate.postForEntity(uploadUrl, requestEntity, String.class);

                // 处理响应
                if (responseEntity.getStatusCode() == HttpStatus.OK) {
                    // 上传成功，设置响应信息
                    response.setContentType("application/json");
                    response.setCharacterEncoding("UTF-8");
                    PrintWriter out = response.getWriter();
                    out.print("{\"status\":\"success\",\"message\":\"文件已成功上传到MinIO\",\"fileName\":\"" + pileNumber + "#桩基质检及收方资料.xlsx\"}");
                    out.println(responseEntity.getBody());
                    out.flush();
                } else {
                    // 上传失败，设置错误响应
                    response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                    response.setContentType("application/json");
                    response.setCharacterEncoding("UTF-8");
                    PrintWriter out = response.getWriter();
                    out.print("{\"status\":\"error\",\"message\":\"文件上传失败：" + responseEntity.getBody() + "\"}");
                    out.flush();
                }
            }
        } catch (Exception e) {
            try {
                // 设置错误响应
                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                response.setContentType("application/json");
                response.setCharacterEncoding("UTF-8");
                PrintWriter out = response.getWriter();
                out.print("{\"status\":\"error\",\"message\":\"处理文件时出错：" + e.getMessage() + "\"}");
                out.flush();
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
            throw new RuntimeException(e);
        } finally {
            // 删除临时文件
            if (tempFilePath != null) {
                try {
                    Files.deleteIfExists(tempFilePath);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    @Override
    public void createPuringTable2toMinio(int id, HttpServletResponse response) {
        PileData pileData = pileDataMapper.selectById(id);
        PilePouringRecord pilePouringRecord = createPileRecord(pileData);
        List<ControlPoints> controlPoints = controlPointsService.list();
        ControlPoints controlPoint = getControlpoint(pileData, controlPoints);
        ControlPoints controlPoint1 = getControlpoint(controlPoint, controlPoints);

        Path tempFilePath = null;
        FileOutputStream fos = null;
        InputStream inputStream = null;
        XSSFWorkbook excel = null;

        try {
            inputStream = this.getClass().getClassLoader().getResourceAsStream("template/桩基质检资料筑业版.xlsx");
            if (inputStream == null) {
                throw new IOException("模板文件未找到");
            }
            excel = new XSSFWorkbook(inputStream);
            ApplicationFormforConstructionQualityInspectionandApprovalofUnitProject.creatApplicationForInspection(excel,pileData);

            String targetFileName = pileData.getPileNumber() + "号桩基质检资料筑业版.xlsx";
            tempFilePath = Files.createTempFile("pile-data2-", ".xlsx");
            File tempFile = tempFilePath.toFile();


            fos = new FileOutputStream(tempFile); // 手动创建流
            excel.write(fos); // 手动写入文件

            // 手动关闭流（注意顺序：先写入的后关闭）
            if (fos != null) {
                fos.close();
            }
            if (excel != null) {
                excel.close();
            }
            if (inputStream != null) {
                inputStream.close();
            }

            // 上传文件逻辑（与原代码一致）
            FileSystemResource fileResource = new FileSystemResource(tempFile) {
                @Override
                public String getFilename() {
                    return targetFileName;
                }
            };

            Long userId = 1L;
            String operation = "资料数据2";
            RestTemplate restTemplate = new RestTemplate();
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.MULTIPART_FORM_DATA);

            MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
            body.add("file", fileResource);
            body.add("userId", userId);
            body.add("pileNumber", pileData.getPileNumber());
            body.add("operation", operation);

            String uploadUrl = "http://192.168.1.245:8081/file/upload";
            ResponseEntity<String> responseEntity = restTemplate.postForEntity(uploadUrl, body, String.class);

            // 处理响应（与原代码一致）
            if (responseEntity.getStatusCode() == HttpStatus.OK) {
                response.setContentType("application/json");
                response.setCharacterEncoding("UTF-8");
                PrintWriter out = response.getWriter();
                out.print("{\"status\":\"success\",\"message\":\"文件已成功上传到MinIO\",\"fileName\":\"" + targetFileName + "\"}");
                out.flush();
            } else {
                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                response.setContentType("application/json");
                response.setCharacterEncoding("UTF-8");
                PrintWriter out = response.getWriter();
                out.print("{\"status\":\"error\",\"message\":\"文件上传失败：" + responseEntity.getBody() + "\"}");
                out.flush();
            }

        } catch (Exception e) {
            try {
                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                response.setContentType("application/json");
                response.setCharacterEncoding("UTF-8");
                PrintWriter out = response.getWriter();
                out.print("{\"status\":\"error\",\"message\":\"处理文件时出错：" + e.getMessage() + "\"}");
                out.flush();
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
            throw new RuntimeException(e);
        } finally {
            // 删除临时文件（与原代码一致）
            if (tempFilePath != null) {
                try {
                    Files.deleteIfExists(tempFilePath);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
            // 确保流在 finally 中再次关闭（应对可能的异常）
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
            if (excel != null) {
                try {
                    excel.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        }
    }

    @Override
    public List<PileData> getPileDataByPouringTimeRange(Date startTime, Date endTime) {
        return pileDataMapper.selectByPouringTimeRange(startTime, endTime);
    }

    //@Override
    public void createPuringTabletoMiniobak1(int id, HttpServletResponse response) {
        PileData pileData = pileDataMapper.selectById(id);
        PilePouringRecord pilePouringRecord = createPileRecord(pileData);
        List<ControlPoints> controlPoints = controlPointsService.list();
        ControlPoints controlPoint = getControlpoint(pileData, controlPoints);
        ControlPoints controlPoint1 = getControlpoint(controlPoint, controlPoints);

        Path tempFilePath = null;
        FileOutputStream fos = null;
        InputStream inputStream = null;
        XSSFWorkbook excel = null;

        try {
            inputStream = this.getClass().getClassLoader().getResourceAsStream("template/桩基质检及收方资料.xlsx");
            if (inputStream == null) {
                throw new IOException("模板文件未找到");
            }

            excel = new XSSFWorkbook(inputStream);
            createSheet1(excel, pilePouringRecord);

            createSheet2(excel, controlPoint, controlPoint1, pileData);

            double elevation = pileData.getPileTopElevation() + generateRandomNumber(1, 1.2); //实测地面高程
            double surfaceelevation = elevation - generateRandomNumber(12, 15); //岩石高程
            double casingTopElevation = Double.parseDouble(pilePouringRecord.getCasingTopElevation()); //护筒顶高程
            double drillingDepth = elevation - Double.parseDouble(pilePouringRecord.getPrePouringHoleBottomElevation()); //钻井深度
            //creatSheet3(excel, pilePouringRecord, elevation, pileData, casingTopElevation, surfaceelevation, drillingDepth);

            HiddenAcceptance.creatsheet5(excel.getSheet("Sheet5"),excel,pileData);
            ThreeInspectionsRecord.creatsheet6(excel.getSheet("Sheet6"),excel,pileData);
            ThreeInspectionsRecord.creatsheet7(excel.getSheet("Sheet7"),excel,pileData);
            //混凝土申请记录表
            pilePouringRecord.setPilePosition("(K0+"+pileData.getMileage()+")"+pileData.getPileNumber()+"#桩");
            createSheet8(excel, pilePouringRecord);

            String targetFileName = pileData.getPileNumber() + "号桩基质检及收方资料.xlsx";
            tempFilePath = Files.createTempFile("pile-data-", ".xlsx");
            File tempFile = tempFilePath.toFile();

            fos = new FileOutputStream(tempFile); // 手动创建流
            excel.write(fos); // 手动写入文件

            // 手动关闭流（注意顺序：先写入的后关闭）
            if (fos != null) {
                fos.close();
            }
            if (excel != null) {
                excel.close();
            }
            if (inputStream != null) {
                inputStream.close();
            }

            // 上传文件逻辑（与原代码一致）
            FileSystemResource fileResource = new FileSystemResource(tempFile) {
                @Override
                public String getFilename() {
                    return targetFileName;
                }
            };

            Long userId = 1L;
            String operation = "资料数据";
            RestTemplate restTemplate = new RestTemplate();
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.MULTIPART_FORM_DATA);

            MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
            body.add("file", fileResource);
            body.add("userId", userId);
            body.add("pileNumber", pileData.getPileNumber());
            body.add("operation", operation);

            String uploadUrl = "http://192.168.1.245:8081/file/upload";
            ResponseEntity<String> responseEntity = restTemplate.postForEntity(uploadUrl, body, String.class);

            // 处理响应（与原代码一致）
            if (responseEntity.getStatusCode() == HttpStatus.OK) {
                response.setContentType("application/json");
                response.setCharacterEncoding("UTF-8");
                PrintWriter out = response.getWriter();
                out.print("{\"status\":\"success\",\"message\":\"文件已成功上传到MinIO\",\"fileName\":\"" + targetFileName + "\"}");
                out.flush();
            } else {
                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                response.setContentType("application/json");
                response.setCharacterEncoding("UTF-8");
                PrintWriter out = response.getWriter();
                out.print("{\"status\":\"error\",\"message\":\"文件上传失败：" + responseEntity.getBody() + "\"}");
                out.flush();
            }

        } catch (Exception e) {
            try {
                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                response.setContentType("application/json");
                response.setCharacterEncoding("UTF-8");
                PrintWriter out = response.getWriter();
                out.print("{\"status\":\"error\",\"message\":\"处理文件时出错：" + e.getMessage() + "\"}");
                out.flush();
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
            throw new RuntimeException(e);
        } finally {
            // 删除临时文件（与原代码一致）
            if (tempFilePath != null) {
                try {
                    Files.deleteIfExists(tempFilePath);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
            // 确保流在 finally 中再次关闭（应对可能的异常）
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
            if (excel != null) {
                try {
                    excel.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
    @Override
    public void createPuringTabletoMinio(int id, HttpServletResponse response) {
        PileData pileData = pileDataMapper.selectById(id);
        PilePouringRecord pilePouringRecord = createPileRecord(pileData);
        List<ControlPoints> controlPoints = controlPointsService.list();
        ControlPoints controlPoint = getControlpoint(pileData, controlPoints);
        ControlPoints controlPoint1 = getControlpoint(controlPoint, controlPoints);

        Path tempFilePath = null;
        FileOutputStream fos = null;
        InputStream inputStream = null;
        XSSFWorkbook excel = null;

        try {
            inputStream = this.getClass().getClassLoader().getResourceAsStream("template/桩基质检及收方资料.xlsx");
            if (inputStream == null) {
                throw new IOException("模板文件未找到");
            }

            excel = new XSSFWorkbook(inputStream);
            createSheet1(excel, pilePouringRecord);

            createSheet2(excel, controlPoint, controlPoint1, pileData);

            /*double elevation = pileData.getPileTopElevation() + generateRandomNumber(1, 1.2); //实测地面高程
            double surfaceelevation = elevation - generateRandomNumber(12, 15); //岩石高程
            double casingTopElevation = Double.parseDouble(pilePouringRecord.getCasingTopElevation()); //护筒顶高程
            double drillingDepth = elevation - Double.parseDouble(pilePouringRecord.getPrePouringHoleBottomElevation()); //钻井深度

            creatSheet3(excel, pilePouringRecord, elevation, pileData, casingTopElevation, surfaceelevation, drillingDepth);*/
            creatSheet3(excel, pilePouringRecord, pileData);

            HiddenAcceptance.creatsheet5(excel.getSheet("Sheet5"),excel,pileData);
            ThreeInspectionsRecord.creatsheet6(excel.getSheet("Sheet6"),excel,pileData);
            ThreeInspectionsRecord.creatsheet7(excel.getSheet("Sheet7"),excel,pileData);
            //混凝土申请记录表
            pilePouringRecord.setPilePosition("(K0+"+pileData.getMileage()+")"+pileData.getPileNumber()+"#桩");
            createSheet8(excel, pilePouringRecord);

            String targetFileName = pileData.getPileNumber() + "号桩基质检及收方资料.xlsx";
            tempFilePath = Files.createTempFile("pile-data-", ".xlsx");
            File tempFile = tempFilePath.toFile();

            fos = new FileOutputStream(tempFile); // 手动创建流
            excel.write(fos); // 手动写入文件


            /*//----------- 测试代码后续删除------------
            String outputFilePath = "D:\\devtool\\zhuangji\\src\\main\\resources\\template\\桩基质检及收方资料_新版.xlsx";
            try (FileOutputStream out = new FileOutputStream(outputFilePath)) {
                excel.write(out);
                if (1!=0) {
                    return;
                }

            }

            //-------------------------*/
            // 手动关闭流（注意顺序：先写入的后关闭）
            if (fos != null) {
                fos.close();
            }
            if (excel != null) {
                excel.close();
            }
            if (inputStream != null) {
                inputStream.close();
            }

            // 上传文件逻辑（与原代码一致）
            FileSystemResource fileResource = new FileSystemResource(tempFile) {
                @Override
                public String getFilename() {
                    return targetFileName;
                }
            };

            Long userId = 1L;
            String operation = "资料数据";
            RestTemplate restTemplate = new RestTemplate();
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.MULTIPART_FORM_DATA);

            MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
            body.add("file", fileResource);
            body.add("userId", userId);
            body.add("pileNumber", pileData.getPileNumber());
            body.add("operation", operation);

            String uploadUrl = "http://192.168.1.245:8081/file/upload";
            ResponseEntity<String> responseEntity = restTemplate.postForEntity(uploadUrl, body, String.class);

            // 处理响应（与原代码一致）
            if (responseEntity.getStatusCode() == HttpStatus.OK) {
                response.setContentType("application/json");
                response.setCharacterEncoding("UTF-8");
                PrintWriter out = response.getWriter();
                out.print("{\"status\":\"success\",\"message\":\"文件已成功上传到MinIO\",\"fileName\":\"" + targetFileName + "\"}");
                out.flush();
            } else {
                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                response.setContentType("application/json");
                response.setCharacterEncoding("UTF-8");
                PrintWriter out = response.getWriter();
                out.print("{\"status\":\"error\",\"message\":\"文件上传失败：" + responseEntity.getBody() + "\"}");
                out.flush();
            }

        } catch (Exception e) {
            try {
                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                response.setContentType("application/json");
                response.setCharacterEncoding("UTF-8");
                PrintWriter out = response.getWriter();
                out.print("{\"status\":\"error\",\"message\":\"处理文件时出错：" + e.getMessage() + "\"}");
                out.flush();
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
            throw new RuntimeException(e);
        } finally {
            // 删除临时文件（与原代码一致）
            if (tempFilePath != null) {
                try {
                    Files.deleteIfExists(tempFilePath);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
            // 确保流在 finally 中再次关闭（应对可能的异常）
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
            if (excel != null) {
                try {
                    excel.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        }
    }

    private void creatSheet3(XSSFWorkbook excel, PilePouringRecord pilePouringRecord, PileData pileData) {

        double elevation =pileData.getGroundElevation();  // pileData.getPileTopElevation() + generateRandomNumber(1, 1.2); //实测地面高程
        double surfaceelevation =pileData.getElevationBetweenRockAndSoil(); //elevation - generateRandomNumber(12, 15); //岩石高程
        double casingTopElevation =pileData.getElevationCasingPipe();  // Double.parseDouble(pilePouringRecord.getCasingTopElevation()); //护筒顶高程
        double drillingDepth =elevation-pileData.getActualPileBottomElevation(); //elevation - Double.parseDouble(pilePouringRecord.getPrePouringHoleBottomElevation()); //钻井深度


        //成孔记录
        XSSFSheet sheet= excel.getSheet("Sheet3");
        DecimalFormat df = new DecimalFormat("0.000");
        sheet.getRow(1).getCell(0).setCellValue(pilePouringRecord.getPilePosition() );
        sheet.getRow(3).getCell(3).setCellValue(df.format(pileData.getGroundElevation()));
        sheet.getRow(3).getCell(11).setCellValue(pileData.getPileTopElevation());
        sheet.getRow(4).getCell(7).setCellValue(Math.ceil(pileData.getElevationCasingPipe()-pileData.getElevationBetweenRockAndSoil()));//护筒长度
        sheet.getRow(4).getCell(13).setCellValue( pileData.getElevationCasingPipe());
        sheet.getRow(6).getCell(3).setCellValue(drillingDepth);
        sheet.getRow(6).getCell(7).setCellValue(pileData.getActualPileBottomElevation());
        sheet.getRow(6).getCell(13).setCellValue(df.format(surfaceelevation));
        Date time= pileData.getHoleOpeningTime();
         df = new DecimalFormat("0.000");
        int minute=0 ;//耗时分钟数
        sheet.getRow(9).getCell(0).setCellValue(dateToDayTime.toDayTime(time,minute));
        double num1=0;//开始
        double num2=generateRandomNumber(1,2);//开始
        double num3=num2-num1;//长度
        sheet.getRow(9).getCell(7).setCellValue(df.format(num1));
        sheet.getRow(9).getCell(8).setCellValue(df.format(num2));

        double soilDepth= Double.valueOf(df.format(num3));
        sheet.getRow(9).getCell(10).setCellValue(df.format(num3));
        minute=minute+(int)(Math.ceil(3*num3/1)) ;//耗时分钟数
        sheet.getRow(10).getCell(0).setCellValue(dateToDayTime.toDayTime(time,minute));


        sheet.getRow(11).getCell(0).setCellValue(dateToDayTime.toDayTime(time,minute));
        num1=num2;//开始
        num2=generateRandomNumber(2,4);//开始
        num3=num2-num1;//长度
        sheet.getRow(11).getCell(7).setCellValue(df.format(num1));


        sheet.getRow(11).getCell(8).setCellValue(df.format(num2));
        soilDepth=soilDepth+Double.valueOf(df.format(num3));
        sheet.getRow(11).getCell(10).setCellValue(df.format(num3));
        minute=minute+(int)(Math.ceil(5*num3/1)) ;//耗时分钟数
        sheet.getRow(12).getCell(0).setCellValue(dateToDayTime.toDayTime(time,minute));
        sheet.getRow(13).getCell(0).setCellValue(dateToDayTime.toDayTime(time,minute));
        num1=num2;//开始
        num2= elevation - surfaceelevation;//开始
        num3=num2-num1;//长度
        sheet.getRow(13).getCell(7).setCellValue(df.format(num1));
        sheet.getRow(13).getCell(8).setCellValue(df.format(num2));

        double sandyGravelLayerDepth=num3;
        sheet.getRow(13).getCell(10).setCellValue(df.format(num3));
        minute=minute+(int)(Math.ceil(15*num3/1)) ;//耗时分钟数
        Date date1=dateToDayTime.addMinutesToDate(time,minute);//岩土交界时间
        sheet.getRow(14).getCell(0).setCellValue(dateToDayTime.backDayTime(date1,0));
        num1=num2;//开始
        num2= elevation -pileData.getActualPileBottomElevation() ;//开始
        num3=num2-num1;//长度
        sheet.getRow(15).getCell(7).setCellValue(df.format(num1));
        sheet.getRow(15).getCell(8).setCellValue(df.format(num2));

        double sandyMudstoneDepth=num3;
        minute=(int)(Math.ceil(30*num3)) ;//耗时分钟数
        Date date2=dateToDayTime.subtractMinutesFromDate(pileData.getHoleCompletionTime(),minute);//成孔时间倒退分钟数到岩土交界时间
        Date lastdate=dateToDayTime.getLaterDate(date1,date2);

        sheet.getRow(15).getCell(0).setCellValue(dateToDayTime.backDayTime(lastdate,0));
        sheet.getRow(16).getCell(0).setCellValue(dateToDayTime.toDayTime(pileData.getHoleCompletionTime(),0));


        ReceiptStatementPile receiptStatementPile=new ReceiptStatementPile();
        receiptStatementPile.setPileNumber(pileData.getPileNumber()+"#");
        receiptStatementPile.setMeasurementPart("钻孔灌注桩"+receiptStatementPile.getPileNumber());
        receiptStatementPile.setDate(pileData.getHoleCompletionTime());

        receiptStatementPile.setCasingTopElevation(casingTopElevation);
        receiptStatementPile.setCasingBottomElevation( pileData.getElevationCasingPipe()-Math.ceil(pileData.getElevationCasingPipe()-pileData.getElevationBetweenRockAndSoil()));
        receiptStatementPile.setOrificeElevation(elevation);
        receiptStatementPile.setHoleBottomElevation(Double.valueOf(pileData.getActualPileBottomElevation()));
        receiptStatementPile.setSoilDepth(soilDepth);
        receiptStatementPile.setSandyGravelLayerDepth(sandyGravelLayerDepth);
        receiptStatementPile.setSandyMudstoneDepth(sandyMudstoneDepth);
        receiptStatementPile.setCasingWallThickness(4);
        receiptStatementPile.setCasingInnerDiameter(161);
        receiptStatementPile.setHoleDiameter(150);
        receiptStatementPile.setHoleDepth(drillingDepth);
        receiptStatementPile.setCasingLength(Math.ceil(pileData.getElevationCasingPipe()-pileData.getElevationBetweenRockAndSoil()));

        receiptStatementPile.setSandyMudstoneDepth(Double.parseDouble(df.format(receiptStatementPile.getHoleDepth()))-Double.parseDouble(df.format(receiptStatementPile.getSoilDepth()))-Double.parseDouble(df.format(receiptStatementPile.getSandyGravelLayerDepth())));
        sheet.getRow(15).getCell(10).setCellValue(df.format(receiptStatementPile.getSandyMudstoneDepth()));

        InsertIntoExistingExcel.creatReceiptStamentPileTable(receiptStatementPile, sheet.getWorkbook());
    }

    private  void createSheet2(XSSFWorkbook excel, ControlPoints controlPoint, ControlPoints controlPoint1, PileData pileData) throws IOException {
        XSSFSheet sheet= excel.getSheet("Sheet2");

        sheet.getRow(3).getCell(0).setCellValue(controlPoint.getPointName());
        sheet.getRow(2).getCell(1).setCellValue(controlPoint.getCoordinateX()+"");
        sheet.getRow(3).getCell(1).setCellValue(controlPoint.getCoordinateY()+"");
        sheet.getRow(4).getCell(1).setCellValue(controlPoint.getElevationH()+"");
        sheet.getRow(3).getCell(6).setCellValue(controlPoint1.getDescription());

        sheet.getRow(3).getCell(3).setCellValue(controlPoint1.getPointName());
        sheet.getRow(2).getCell(4).setCellValue(controlPoint1.getCoordinateX()+"");
        sheet.getRow(3).getCell(4).setCellValue(controlPoint1.getCoordinateY()+"");
        sheet.getRow(4).getCell(4).setCellValue(controlPoint1.getElevationH()+"");


        DrawImageToExcel.creatImage(2,1, pileData.getPileNumber().substring(0, pileData.getPileNumber().indexOf("-")),8,3,sheet, sheet.getWorkbook());


        sheet.getRow(5).getCell(1).setCellValue("旋挖灌注桩"+ pileData.getPileNumber()+"#");


        sheet.getRow(8).getCell(0).setCellValue(pileData.getPileNumber());
        sheet.getRow(8).getCell(1).setCellValue(pileData.getCoordinateX());
        sheet.getRow(8).getCell(2).setCellValue(pileData.getCoordinateY());
        sheet.getRow(8).getCell(3).setCellValue(pileData.getPileTopElevation());
        double x=new Random().nextInt(10);
        double y=new Random().nextInt(10);
        double d=Math.sqrt(x*x+y*y);
        double h=new Random().nextInt(10);

        DecimalFormat df = new DecimalFormat("0.000");
        sheet.getRow(8).getCell(4).setCellValue(df.format(pileData.getCoordinateX()+(x/1000)));
        sheet.getRow(8).getCell(5).setCellValue(df.format(pileData.getCoordinateY()+(y/1000)));
        sheet.getRow(8).getCell(6).setCellValue(df.format(pileData.getPileTopElevation()+(h/1000)));
        DecimalFormat df1 = new DecimalFormat("0");
        sheet.getRow(8).getCell(7).setCellValue(df1.format(x));
        sheet.getRow(8).getCell(8).setCellValue(df1.format(y));
        sheet.getRow(8).getCell(10).setCellValue(df1.format(h));
        df1 = new DecimalFormat("0.0");
        sheet.getRow(8).getCell(9).setCellValue(df1.format(d));

        sheet.getRow(20).getCell(0).setCellValue("测量：                             复核：                             监理：                            日期："+dateToDayTime.toLoaclDays(pileData.getHoleOpeningTime()) );
    }

    /**
     * 混凝土浇筑记录表
     * @param excel
     * @param pilePouringRecord
     */
    private  void createSheet1(XSSFWorkbook excel, PilePouringRecord pilePouringRecord) {
        XSSFSheet sheet= excel.getSheet("Sheet1");
        sheet.getRow(1).getCell(0).setCellValue(pilePouringRecord.getPilePosition());

        sheet.getRow(3).getCell(3).setCellValue(pilePouringRecord.getDesignPileDiameter());
        sheet.getRow(3).getCell(12).setCellValue(pilePouringRecord.getDesignPileTopElevation());
        sheet.getRow(3).getCell(17).setCellValue(pilePouringRecord.getDesignPileBottomElevation());

        sheet.getRow(4).getCell(3).setCellValue(pilePouringRecord.getPrePouringHoleBottomElevation());
        sheet.getRow(4).getCell(12).setCellValue(pilePouringRecord.getCasingTopElevation());
        sheet.getRow(4).getCell(17).setCellValue(pilePouringRecord.getCalculatedConcreteVolume());

        sheet.getRow(5).getCell(3).setCellValue(pilePouringRecord.getDesignStrengthGrade());
        sheet.getRow(5).getCell(12).setCellValue(pilePouringRecord.getConcreteMixRatioNumber());
        sheet.getRow(5).getCell(17).setCellValue(pilePouringRecord.getTestBlockNumber());

        sheet.getRow(6).getCell(3).setCellValue(pilePouringRecord.getConduitDiameter());
        sheet.getRow(6).getCell(12).setCellValue(pilePouringRecord.getConduitLength());
        sheet.getRow(6).getCell(17).setCellValue(pilePouringRecord.getWaterStopPlugForm());


        sheet.getRow(7).getCell(3).setCellValue(pilePouringRecord.getPouringDate());
        sheet.getRow(7).getCell(14).setCellValue(pilePouringRecord.getClimate());
        List<PileRecord> list= pilePouringRecord.getRecordList();

        for (int i = 0; i < list.size(); i++) {
            PileRecord record=list.get(i);
            System.out.println(record);
            sheet.getRow(10+i).getCell(0).setCellValue(i+1);
            sheet.getRow(10+i).getCell(1).setCellValue(record.getTime());
            sheet.getRow(10+i).getCell(2).setCellValue(record.getConcreteDepthInHole());
            sheet.getRow(10+i).getCell(4).setCellValue(record.getConcreteDepthInConduit());
            sheet.getRow(10+i).getCell(6).setCellValue(record.getRemovedConduitSections());
            sheet.getRow(10+i).getCell(8).setCellValue(record.getConduitLength());
            sheet.getRow(10+i).getCell(10).setCellValue(record.getBuriedDepthOfConduitBottom());
            sheet.getRow(10+i).getCell(13).setCellValue(record.getNumberOfTanks());
            sheet.getRow(10+i).getCell(14).setCellValue(record.getQuantity());
            sheet.getRow(10+i).getCell(16).setCellValue(record.getCumulativeQuantity());
            sheet.getRow(10+i).getCell(17).setCellValue(record.getRemarks());

        }
    }

    /**
     * 混 凝 土 浇 筑 许 可 证
     * @param excel
     * @param pilePouringRecord
     */
    private  void createSheet8(XSSFWorkbook excel, PilePouringRecord pilePouringRecord) {
        XSSFSheet sheet= excel.getSheet("Sheet8");
        sheet.getRow(5).getCell(4).setCellValue(pilePouringRecord.getPilePosition());
        sheet.getRow(6).getCell(4).setCellValue( pilePouringRecord.getPouringDate());
        sheet.getRow(7).getCell(4).setCellValue(pilePouringRecord.getCalculatedConcreteVolume());
        sheet.getRow(8).getCell(4).setCellValue(new Random().nextInt(6)*5+190);
    }

    private ControlPoints getControlpoint(PileData pileData, List<ControlPoints> controlPoints) {
        ControlPoints controlPoint=new ControlPoints();

        double x=pileData.getCoordinateX();
        double y=pileData.getCoordinateY();
        double l=99999;

        for (ControlPoints cp:controlPoints) {
            double x1=Double.valueOf(cp.getCoordinateX()+"") ;
            double y1=Double.valueOf(cp.getCoordinateY()+"") ;
            double l1=Math.sqrt((x-x1)*(x-x1)+(y-y1)*(y-y1));
            if(l1<=l){
                l=l1;
                controlPoint=cp;
            }

        }
        return controlPoint;
    }

    private ControlPoints getControlpoint(ControlPoints c, List<ControlPoints> controlPoints) {
        ControlPoints controlPoint=new ControlPoints();

        double x=Double.valueOf(c.getCoordinateX()+"");
        double y=Double.valueOf(c.getCoordinateY()+"");
        double l=99999;

        for (ControlPoints cp:controlPoints) {
            if(cp.getPointName().equals(c.getPointName())){
                continue;
            }
            double x1=Double.valueOf(cp.getCoordinateX()+"") ;
            double y1=Double.valueOf(cp.getCoordinateY()+"") ;
            double l1=Math.sqrt((x-x1)*(x-x1)+(y-y1)*(y-y1));
            if(l1<=l){
                l=l1;
                controlPoint=cp;
            }

        }
        return controlPoint;
    }

    /**
     *  -1,1 之间的随机数
     * @param min
     * @param max
     * @return
     */
    public static double generateRandomNumber(double min, double max) {
        Random random = new Random();

        return min + random.nextDouble() * (max - min);
    }
    /**
     *  -1,1 之间的随机数
     * @param min
     * @param max
     * @return
     */
    public static int generateRandomNumberInt(int min, int max) {
        Random random = new Random();
        System.out.println("=============>随机数"+(min + random.nextInt(max-min)));
        return min + random.nextInt( max - min);
    }

    private PilePouringRecord createPileRecord(PileData pileData) {
        DecimalFormat df = new DecimalFormat("0.000");
        DecimalFormat df1 = new DecimalFormat("0");
        // 时间
        String time;
        // 孔内混凝土深度
        String concreteDepthInHole;
        // 导管内混凝土深度
        String concreteDepthInConduit;
        // 拆除的导管节数
        String removedConduitSections;
        // 导管长度
        String conduitLength;
        // 导管底部埋深
        String buriedDepthOfConduitBottom;
        // 罐数
        String numberOfTanks;
        // 数量
        String quantity;
        // 累计数量
        String cumulativeQuantity;
        // 备注
        String remarks;

        //开始浇筑时间
        Date beginTime = pileData.getPouringTime();

        //桩底实际高程
        double dataPileBottomElevation=pileData.getActualPileBottomElevation();
        //浇筑长度
        double legth=pileData.getPileTopElevation()- dataPileBottomElevation+pileData.getOverPouringLength();
        // 混凝土方量
        double concreteVolume0= (pileData.getPileDiameter()*pileData.getPileDiameter()/4)*Math.PI*legth;
        //米每方
        double lforv=legth/concreteVolume0;
        //每罐体积
        int number=18;
        //充盈系数
        double fillingcoefficient=pileData.getActualPouringVolume()/concreteVolume0;
        // 罐数 计算所需容器数量，使用 Math.ceil 向上取整
        int numberOfTanks0 = (int) Math.ceil((pileData.getActualPouringVolume()) / number);


        //护筒顶高程
        double casingTopElevation=pileData.getElevationCasingPipe();

        //计算孔深 护筒顶到桩底
        double concreteDepthInHole0=casingTopElevation-dataPileBottomElevation;
        //导管长度 20.55-0.5
        double conduitLength0=Math.ceil(concreteDepthInHole0-0.4);
        // 拆除的导管节数3米
        double conduitlength=3;
        int removedConduitSections0= (int) Math.ceil(conduitLength0 / conduitlength);

        List<PileRecord> list=new ArrayList<PileRecord>();

        /*for (int i = 0; i <=numberOfTanks0; i++) {

            if((i)!=numberOfTanks0) {
                // 开始时间+灌数*（20,25）
                time= dateToDayTime.toTime(beginTime,i*generateRandomNumberInt(35,40));
                // 孔内混凝土深度
                double depth=(concreteDepthInHole0-concreteDepthInHole0/numberOfTanks0*i);
                concreteDepthInHole=df.format( depth);
                // 导管内混凝土深度
                concreteDepthInConduit=df.format( depth-1);

                //todo 拆除的导管节数
                int removedcount=3;;
                removedConduitSections=removedcount+"";
                // 导管长度
                conduitLength=removedcount*conduitlength+"";
                // 导管底部埋深=导管长度-孔内混凝土面深度-导管拆除长度

                buriedDepthOfConduitBottom=df.format((conduitLength0-depth-(i-1)*2*conduitlength));
                // 罐数
                numberOfTanks=i+"";
                // 数量
                quantity=number+"";

                // 累计数量
                cumulativeQuantity=df1.format(i*number);
                // 备注
                remarks="";

                if(i==0){
                    concreteDepthInConduit="0";
                    removedConduitSections="0";
                    conduitLength="0";
                    buriedDepthOfConduitBottom="0";
                    quantity="0";
                    cumulativeQuantity="0";
                    remarks="开始";
                }
                if(i==1){
                    conduitLength="0";
                    removedConduitSections="0";

                }


            }else {
                // 开始时间+灌数*（20,25）
                time=dateToDayTime.toTime(beginTime,i*generateRandomNumberInt(35,40));

                concreteDepthInHole=df.format( concreteDepthInHole0-legth);
                // 导管内混凝土深度
                concreteDepthInConduit= "0";
                //todo 拆除的导管节数
                //int removedcount=(int) Math.ceil(concreteDepthInHole0 / conduitlength)-1-(i-2)*3;;
                int removedcount=removedConduitSections0-(i-2)*3;;

                removedConduitSections=(removedcount-1)+"";
                // 拆除导管长度
                conduitLength=(removedcount-1)*conduitlength+"";
                // 导管底部埋深=导管长度-孔内混凝土面深度
                buriedDepthOfConduitBottom=df.format((conduitLength0-(concreteDepthInHole0-legth)-(i-1-1)*2*conduitlength-(removedcount-1)*conduitlength));
                // 罐数
                numberOfTanks=i+"";
                // 数量
                double concreteVolume1=Math.ceil(concreteVolume0);

                quantity=df1.format((pileData.getActualPouringVolume()-(i-1)*number));
                // 累计数量
                cumulativeQuantity=df1.format(pileData.getActualPouringVolume());
                // 备注
                remarks="结束";


            }
            PileRecord record=new PileRecord(time,concreteDepthInHole,concreteDepthInConduit,removedConduitSections,conduitLength,buriedDepthOfConduitBottom,numberOfTanks,quantity,cumulativeQuantity,remarks);
            list.add(record);
        }*/
        for(int i=0;i<=numberOfTanks0;i++){
            time=dateToDayTime.toTime(beginTime,i*generateRandomNumberInt(35,40));
            numberOfTanks=""+i;
            if(i==0){
                concreteDepthInHole=""+df.format(concreteDepthInHole0);
                concreteDepthInConduit="0";
                removedConduitSections="0";
                conduitLength="0";
                buriedDepthOfConduitBottom="0";
                //numberOfTanks=""+i;
                quantity="0";
                cumulativeQuantity="0";
                remarks="开始";
            }else if(i==numberOfTanks0){

                concreteDepthInHole=""+df.format(pileData.getElevationCasingPipe()-pileData.getPileTopElevation()-1);
                concreteDepthInConduit="0";
                removedConduitSections=""+(removedConduitSections0-(i-1)*2);
                conduitLength=""+df1.format(conduitLength0-(i-1)*2*conduitlength);
                buriedDepthOfConduitBottom="0";
               // numberOfTanks=""+numberOfTanks0;
                quantity=""+(pileData.getActualPouringVolume()-(i-1)*number);
                cumulativeQuantity=pileData.getActualPouringVolume()+"";
                remarks="结束";
            }else {

                double d=concreteDepthInHole0-lforv*number*(i);
                concreteDepthInHole=df.format(d) ; //孔内混凝土高度=孔深-浇筑长度
                concreteDepthInConduit=df.format(d-1);//孔内混凝土高度-1

                double a=i;
                double b=a*conduitlength*2;
                double c=conduitLength0-b;

                removedConduitSections="2";
                conduitLength="6";
                buriedDepthOfConduitBottom=df.format(c-d);
               // numberOfTanks="";
                quantity=""+number;
                cumulativeQuantity=""+i*number;
                remarks="";
            }
            PileRecord record=new PileRecord(time,concreteDepthInHole,concreteDepthInConduit,removedConduitSections,conduitLength,buriedDepthOfConduitBottom,numberOfTanks,quantity,cumulativeQuantity,remarks);
            list.add(record);
        }



        // 创建 ProjectData 对象
        PilePouringRecord PilePouringRecord = new PilePouringRecord(
                "渠江风洞子航运工程",
                "工程名称：渠江风洞子航运工程                              桩位：临巴堤防工程（"+ NumberToKilometerFormat.formatNumberToKilometer(pileData.getMileage(),1) +")"+pileData.getPileNumber()+"#桩孔",
                "中交第四航务工程局有限公司&山东省路桥集团有限公司联合体渠江风洞子航运工程项目项目经理部",
                "" +pileData.getPileDiameter(),
                ""+pileData.getPileTopElevation(),
                ""+pileData.getPileBottomElevation(),
                df.format(dataPileBottomElevation),
                df.format(casingTopElevation),
                df.format(concreteVolume0),
                "C35(水下)",
                "DZ-风洞子临巴堤防G202500001",
                "DZ-临巴堤防-"+pileData.getTestBlockNumber(),
                "300",
                df1.format(conduitLength0),
                "活塞式",
                dateToDayTime.toLoaclDays(pileData.getPouringTime()),
                pileData.getWeather()+"℃",
                list
        );


        return PilePouringRecord;
    }

    private static String encodeFileName(String userAgent, String fileName) throws IOException {
        if (userAgent != null) {
            if (userAgent.contains("MSIE") || userAgent.contains("Trident")) {
                // IE 浏览器
                return URLEncoder.encode(fileName, "UTF-8").replace("+", " ");
            } else if (userAgent.contains("Mozilla")) {
                // Firefox、Chrome 等现代浏览器
                return "\"" + new String(fileName.getBytes("UTF-8"), "ISO-8859-1") + "\"";
            }
        }
        // 默认编码
        return URLEncoder.encode(fileName, "UTF-8").replace("+", " ");
    }

    // 实现统计方法
    @Override
    public Integer countCompletedPiles() {
        return pileDataMapper.countCompletedPiles();
    }

    @Override
    public PileData getPileDataByPileNumber(String pileNumber) {
        QueryWrapper<PileData> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("pile_number", pileNumber);
        return pileDataMapper.selectOne(queryWrapper);
    }
}